package com.wn.framework.ext

import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow

/**
 * @Author: wn
 * @Date: 2024/12/27 16:42
 * @Description: 将 editText 的回调转为 flow
 *
 * EditText.textChangeFlow()     // 构建输入框文字变化流
 * .filter { it.isNotEmpty() }   // 过滤空内容，避免无效网络请求
 * .debounce(300)                // 300ms防抖
 * .flatMapLatest { searchFlow(it.toString()) } // 新搜索覆盖旧搜索
 * .flowOn(Dispatchers.IO)       // 让搜索在异步线程中执行
 * .onEach { updateUi(it) }      // 获取搜索结果并更新界面
 * .launchIn(mainScope)          // 相当于 scope.launch{ flow.collect } 终止操作 ,所以一般搭配 onEach 一起使用 ,onEach { 执行 collect 中的操作 }
 */
@OptIn(ExperimentalCoroutinesApi::class)
fun EditText.textChangeFlow(): Flow<String> = callbackFlow {
  val watcher = object : TextWatcher {
    override fun afterTextChanged(s: Editable?) {}
    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
      s?.let { trySend(it.toString()) }
    }
  }
  addTextChangedListener(watcher)
  awaitClose { removeTextChangedListener(watcher) } // 阻塞以保证流一直运行
}